﻿#include "SymbolDetail.h"
#include <fstream>
#include "Tools.h"
#include "FileOperator.h"
#ifdef __linux__
#include <cstring>
#endif
#include "OptionManager.h"

SymbolPackage::SymbolsReader::SymbolsReader(time_t cuTime)
	: SymbolsReader(Tools::GetDateTimeFrmStamp(cuTime))
{
}

SymbolPackage::SymbolsReader::SymbolsReader(const std::string &psymbolFileBin, bool beAbsPath)
{
	m_symbolFileBin = psymbolFileBin;
}

SymbolPackage::SymbolsReader::SymbolsReader(tm cuTime)
{
	std::string symbolDir = OptionManager::Instance().GetSymbolDir();
	std::string dateStr = Tools::DateToStr(cuTime);
	symbolDir += dateStr;
	// 创建目录
	m_symbolFileBin = symbolDir + ".symbols";
}

SymbolPackage::SymbolInfo SymbolPackage::SymbolsReader::GetSymbolInfo(const std::string &pSymbol)
{
	SymbolInfo pFInfo;
	memset(&pFInfo, 0, sizeof(SymbolInfo));
	FileOperator::FileBin symbolFile(m_symbolFileBin.c_str());
	if (symbolFile.FileInstance() != nullptr)
	{
		fseek(symbolFile.FileInstance(), 0, SEEK_END);
		int len = ftell(symbolFile.FileInstance());
		int ksize = len / sizeof(SymbolInfo);
		fseek(symbolFile.FileInstance(), 0, SEEK_SET);
		for (int i = 0; i < ksize; ++i)
		{
			fread(&pFInfo, sizeof(SymbolInfo), 1, symbolFile.FileInstance());
			if (pSymbol.compare(pFInfo.InstrumentID) == 0)
			{
				break;
			}
		}
	}
	return pFInfo;
}

void SymbolPackage::SymbolsReader::GetAllSymbolInfoList(std::list<SymbolPackage::SymbolInfo> &outSymbolList)
{
	SymbolInfo pFInfo;
	//memset(&pFInfo, 0, sizeof(SymbolInfo));
	FileOperator::FileBin symbolFile(m_symbolFileBin.c_str(), "rb");
	if (symbolFile.FileInstance() != nullptr)
	{
		fseek(symbolFile.FileInstance(), 0, SEEK_END);
		int len = ftell(symbolFile.FileInstance());
		int ksize = len / sizeof(SymbolInfo);
		fseek(symbolFile.FileInstance(), 0, SEEK_SET);
		for (int i = 0; i < ksize; ++i)
		{
			fread(&pFInfo, sizeof(SymbolInfo), 1, symbolFile.FileInstance());
			outSymbolList.emplace_back(pFInfo);
		}
	}
}

void SymbolPackage::SymbolsReader::GetAllFutureList(std::list<SymbolInfo> &outSymbolList)
{
	std::list<SymbolInfo> pSymbollist;
	GetAllSymbolInfoList(pSymbollist);
	for (std::list<SymbolInfo>::iterator it = pSymbollist.begin(); it != pSymbollist.end(); ++it)
	{
		if (it->ProductClass == '1')
		{
			outSymbolList.emplace_back(*it);
		}
	}
}

SymbolPackage::SymbolListToChar::SymbolListToChar(const std::list<std::string> &pSymbolList)
{
	m_symbolSize = pSymbolList.size();
	m_symbolArray = new char*[m_symbolSize];
	int symbolIndex = 0;
	for (std::list<std::string>::const_iterator it = pSymbolList.begin(); it != pSymbolList.end(); ++it, ++symbolIndex)
	{
		m_symbolArray[symbolIndex] = new char[it->length() + 1];
		strncpy(m_symbolArray[symbolIndex], it->c_str(), it->length());
		m_symbolArray[symbolIndex][it->length()] = 0;
	}
}

SymbolPackage::SymbolListToChar::~SymbolListToChar()
{
	for (int i = 0; i < m_symbolSize; ++i)
	{
		delete m_symbolArray[i];
	}
	delete[] m_symbolArray;
}

char ** SymbolPackage::SymbolListToChar::GetSymbolArray()
{
	return m_symbolArray;
}

int SymbolPackage::SymbolListToChar::GetSymbolsSize()
{
	return m_symbolSize;
}
//
//SymbolPackage::SymbolsGroupRecorder::SymbolsGroupRecorder(const std::string &pWorkspace)
//{
//	std::string symbolDir = OptionManager::Instance().GetSymbolDir();
//	time_t cuTime = Tools::GetCurrentTimeStamp();
//	tm tmStruct = Tools::GetDateTimeFrmStamp(cuTime);
//	std::string dateStr = Tools::DateToStr(tmStruct);
//	symbolDir += dateStr;
//	// 创建目录
//	//Tools::CreateDir(symbolDir);
//	m_symbolFileBin = symbolDir + ".symbols";
//}
//
//void SymbolPackage::SymbolsGroupRecorder::AppendSymbol(CThostFtdcInstrumentField *pInstrument)
//{
//	if (pInstrument == nullptr)
//	{
//		return;
//	}
//	m_sybolList.emplace_back(SymbolInfo());
//	SymbolInfo &contract = m_sybolList.back();
//	contract.ProductClass = pInstrument->ProductClass;
//	strncpy(contract.InstrumentID, pInstrument->InstrumentID, strlen(pInstrument->InstrumentID));
//	contract.InstrumentID[strlen(pInstrument->InstrumentID)] = 0;
//	strncpy(contract.ExchangeID, pInstrument->ExchangeID, strlen(pInstrument->ExchangeID));
//	contract.ExchangeID[strlen(pInstrument->ExchangeID)] = 0;
//	strncpy(contract.InstrumentName, pInstrument->InstrumentName, strlen(pInstrument->InstrumentName));
//	contract.InstrumentName[strlen(pInstrument->InstrumentName)] = 0;
//	contract.VolumeMultiple = pInstrument->VolumeMultiple;
//	contract.PriceTick = pInstrument->PriceTick;
//	contract.LongMarginRatio = pInstrument->LongMarginRatio;
//	contract.ShortMarginRatio = pInstrument->ShortMarginRatio;
//	contract.MaxMarketOrderVolume = pInstrument->MaxMarketOrderVolume;
//	contract.MinMarketOrderVolume = pInstrument->MinMarketOrderVolume;
//	contract.MaxLimitOrderVolume = pInstrument->MaxLimitOrderVolume;
//	contract.MinLimitOrderVolume = pInstrument->MinLimitOrderVolume;
//	contract.DeliveryYear = pInstrument->DeliveryYear;
//	contract.DeliveryMonth = pInstrument->DeliveryMonth;
//}
//
//void SymbolPackage::SymbolsGroupRecorder::SaveSymbols()
//{
//	// 保存二进制
//	FileOperator::FileBin symbolFile(m_symbolFileBin.c_str(), "wb");
//	if (symbolFile.FileInstance() != nullptr)
//	{
//		for (std::list<SymbolInfo>::iterator itSymbol = m_sybolList.begin(); itSymbol != m_sybolList.end(); ++itSymbol)
//		{
//			const SymbolInfo &tmpInfo = *itSymbol;
//			fwrite(&tmpInfo, sizeof(SymbolInfo), 1, symbolFile.FileInstance());
//		}
//	}
//
//}

SymbolPackage::OrderSymbolReaderWriter::OrderSymbolReaderWriter()
{
	std::string symbolDir = OptionManager::Instance().GetSymbolDir();
	// 创建目录
	//Tools::CreateDir(symbolDir);
	m_symbolFile = symbolDir + "OrderSymbols.txt";
}

void SymbolPackage::SymbolReaderWriterText::AppendSymbol(const std::string &pSymbol)
{
	m_symbolList.insert(pSymbol);
}

void SymbolPackage::SymbolReaderWriterText::Save()
{
	std::string symbolList;
	for (std::set<std::string>::iterator it = m_symbolList.begin(); it != m_symbolList.end(); ++it)
	{
		symbolList += *it + ',';
	}
	if (!symbolList.empty())
	{
		if (symbolList.back() == ',')
		{
			symbolList.erase(symbolList.length() - 1);
		}
	}

	std::fstream f(m_symbolFile, std::ios::out);//供写使用，文件不存在则创建，存在则清空原内容
	f << symbolList; //写入数据
	f.close();//关闭文件以使其重新变为可访问，函数一旦调用，原先的流对象就可以被用来打开其它的文件

}

void SymbolPackage::SymbolReaderWriterText::GetSymbolList(std::list<std::string> &oSymbolList)
{
	std::ifstream readFile(m_symbolFile);
	if (!readFile.is_open())
	{
		readFile.close();
		return;
	}
	std::string lineStr;
	std::getline(readFile, lineStr);
	readFile.close();
	if (!lineStr.empty())
	{
		std::vector<std::string > symbolist;
		Tools::Split(lineStr.c_str(), ',', symbolist);
		for (std::vector<std::string >::iterator it = symbolist.begin(); it != symbolist.end(); ++it)
		{
			oSymbolList.emplace_back(*it);
		}
	}
}

SymbolPackage::MainSymbolReaderWriter::MainSymbolReaderWriter(tm cuTime)
{
	std::string symbolDir = OptionManager::Instance().GetSymbolDir();
	std::string dateStr = Tools::DateToStr(cuTime);
	symbolDir += dateStr;
	m_symbolFile = symbolDir + ".maincontent";
}

void SymbolPackage::GetTheLastFutureSymbolInfoList(std::list<SymbolInfo> &outList)
{
	// 取今天之前的十天时间，以防今日的合约获取失败
	time_t cutime = Tools::GetCurrentTimeStamp();
	tm tmStr = Tools::GetDateTimeFrmStamp(cutime);
	tm tendays[10];
	tendays[0] = tmStr;
	for (int i = 1; i < 10; ++i)
	{
		tendays[i] = Tools::AddDays(tmStr, -i);
	}
	for (int i = 0; i < 10; ++i)
	{
		SymbolsReader symbolManager(tendays[i]);
		std::list<SymbolInfo> pSymbolList;
		symbolManager.GetAllFutureList(pSymbolList);
		if (!pSymbolList.empty())
		{
			outList.swap(pSymbolList);
			break;
		}
	}
}

void SymbolPackage::GetTheLastMainSymbolList(std::list<std::string> &outList, time_t theLastTime)
{
	// 取今天之前的十天时间，以防今日的合约获取失败
	//time_t cutime = Tools::GetCurrentTimeStamp();
	tm tmStr = Tools::GetDateTimeFrmStamp(theLastTime);
	tm tendays[10];
	tendays[0] = tmStr;
	for (int i = 1; i < 10; ++i)
	{
		tendays[i] = Tools::AddDays(tmStr, -i);
	}
	for (int i = 0; i < 10; ++i)
	{
		MainSymbolReaderWriter symbolManager(tendays[i]);
		std::list<std::string> pSymbolList;
		symbolManager.GetSymbolList(pSymbolList);
		if (!pSymbolList.empty())
		{
			outList.swap(pSymbolList);
			break;
		}
	}
}
